/*
Copyright (c) 2008 André Luiz Alves Moraes

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
 */

package andre.grids.filesystem.server.configuration;

import andre.grids.util.*;

import andre.grids.db.*;
import andre.grids.db.dataclasses.*;
import andre.grids.network.MasterPeerTable;
import andre.grids.util.log.*;
import java.io.*;
import java.util.*;

/**
 *
 * @author andre
 */
public class ConfigurationManager {
    
    private static final String BASE_CONFIG_NAME = "base.config";
    private static final String FILE_SYS_CONFIG_PROP = "file_sys_config_file";
    private static final String DB_SYS_CONFIG_PROP = "db_file_config";
    
    private static Configuration baseConfig;
    private static Configuration filesysConfig;
    private static Configuration dbConfig;
    
    public static void loadServer()
    {
        loadServer(BASE_CONFIG_NAME);
    }
    
    public static void loadServer(String baseConfigFile)
    {
        java.io.File file = new java.io.File(baseConfigFile);
        if (!file.exists())
        {
            System.err.println("Arquivo de configuração informado não existe: " + baseConfigFile);
            System.exit(1);
        }
        file = null;
        
        baseConfig = new Configuration(baseConfigFile);
        String filesysConfigStr = baseConfig.getValue(FILE_SYS_CONFIG_PROP);
        if (filesysConfigStr.equals(""))
        {
            System.err.println("O valor de " + FILE_SYS_CONFIG_PROP + " deve ser configurado em: " + baseConfigFile);
            System.exit(1);
        }
        filesysConfig = new Configuration(filesysConfigStr);
        
        String dbConfigStr = baseConfig.getValue(DB_SYS_CONFIG_PROP);
        if(dbConfigStr.equals(""))
        {
            System.err.println("O valor de " + DB_SYS_CONFIG_PROP + " deve ser configurado em: " + baseConfigFile);
            System.exit(1);
        }
        dbConfig = new Configuration(dbConfigStr);
    }
    
    public static void initializeDb()
    {
        DbPeer peer = new DbPeer();
        DbPeerQueries query = new DbPeerQueries();
        DbPeer p = query.getPeerByName(getBaseConfigInstance().getValue(ServerConfigurationProps.SERVER_HOST_NAME));
        query = null;
        if (p == null) {
            /*
             * Se não achou ninguém com o nome do servidor atual, 
             * então precisa criar a entrada na tabela de masters e no banco
             */
            MasterPeerTable.getInstance().addPeer(getBaseConfigInstance().getValue(ServerConfigurationProps.SERVER_HOST_NAME));
        }
    }
    
    public static Configuration getFileSystemConfigInstance()
    {
        return filesysConfig;
    }
    
    public static Configuration getDbConfigInstance()
    {
        return dbConfig;
    }
    
    public static Configuration getBaseConfigInstance()
    {
        return baseConfig;
    }
    
    public static String[] getDirMasterList() {
        
        Vector<String> result = new Vector<String>();
        Configuration config = getBaseConfigInstance();
        
        try
        {
            Scanner scan = new Scanner(new FileInputStream(config.getValue(ServerConfigurationProps.SERVER_MASTER_PEERS_LIST)));
            String linha = null;
            while(scan.hasNextLine())
            {
                linha = scan.nextLine();
                result.add(linha);
            }
        }
        catch(Exception e)
        {
            andre.grids.util.log.Log.logException(e, config, true);
        }
        
        String [] res = new String[result.size()];
        
        result.toArray(res);
        return res;
    }
    
    public static String[] getFileServerList() {
        Vector<String> result = new Vector<String>();
        Configuration config = getBaseConfigInstance();
        
        try
        {
            Scanner scan = new Scanner(new FileInputStream(config.getValue(ServerConfigurationProps.SERVER_FILE_SERVER_LIST)));
            String linha = null;
            while(scan.hasNextLine())
            {
                linha = scan.nextLine();
                result.add(linha);
            }
        }
        catch(Exception e)
        {
            andre.grids.util.log.Log.logException(e, config, true);
        }
        
        String [] res = new String[result.size()];
        
        result.toArray(res);
        return res;        
    }
    
    public static boolean isFsServer() {
        return getBaseConfigInstance().getValue(ServerConfigurationProps.SERVER_TYPE).equals("fileserver");
    }
    
    public static boolean isDmServer() {
        return getBaseConfigInstance().getValue(ServerConfigurationProps.SERVER_TYPE).equals("dmserver");
    }
    
    public static long getLastBeat() {
        try {
            Scanner scan = new Scanner(new FileInputStream(getBaseConfigInstance().getValue(ServerConfigurationProps.SERVER_HEART_BEATS_FILE)));
            long result = 0;
            if (scan.hasNextLong())
                result = scan.nextLong();
            scan.close();
            return result;            
        } catch(FileNotFoundException e) {
                System.err.println("Arquivo de heart-beats não encontrado, assumindo 0");
                return 0;
        } catch(Exception e) {
            Log.logException(e, e, true);
            return -1;
        }
    }
    
    public static void beat(long beatTime) {
        try {
            File f = new File(getBaseConfigInstance().getValue(ServerConfigurationProps.SERVER_HEART_BEATS_FILE));
            f.createNewFile();
            
            PrintStream writer = new PrintStream(new FileOutputStream(f));
            writer.println(beatTime);
            writer.flush();
            writer.close();
        } catch(IOException e) {
            Log.logException(e, e, true);
        }
    }
    
    public static long beat() {
        try {
            File f = new File(getBaseConfigInstance().getValue(ServerConfigurationProps.SERVER_HEART_BEATS_FILE));
            f.createNewFile();
            
            PrintStream writer = new PrintStream(new FileOutputStream(f));
            long beatTime = System.currentTimeMillis();
            writer.println(beatTime);
            writer.flush();
            writer.close();
            return beatTime;
        } catch(IOException e) {
            Log.logException(e, e, true);
            return -1;
        }
    }
}
